package com.voodoo.serialport;

import com.voodoo.serialport.callback.SerialPortTtys2CallBack;
import com.voodoo.lib_logcat.L;
import com.voodoo.serialport.SerialPortHelper;
import com.voodoo.serialport.entity.BAUDRATE;
import com.voodoo.serialport.entity.DATAB;
import com.voodoo.serialport.entity.FLOWCON;
import com.voodoo.serialport.entity.PARITY;
import com.voodoo.serialport.entity.STOPB;
import com.voodoo.serialport.listener.IOpenSerialPortListener;
import com.voodoo.serialport.listener.ISerialPortDataListener;
import com.voodoo.serialport.listener.Status;

import java.io.File;
import java.util.Arrays;

import static com.voodoo.serialport.util.ByteUtils.byteArrToHex;


/**
 * Author: voodoo
 * CreateDate: 2020-03-26 026 下午 02:34
 * Description: 串口工具类 打开、关闭、发送和接收
 */
public class SerialPortTtys2Util {

    // 记录当前串口是否是打开状态(true:打开,false:关闭)
    public static boolean isSerialPortOpen = false;

    public static SerialPortHelper mSerialPortHelper = null;
    public static String PortName = "/dev/ttyS2";

    /**
     * 打开串口
     */
    public static boolean open() {
        if (mSerialPortHelper == null) {
            mSerialPortHelper = new SerialPortHelper();
            mSerialPortHelper.setPort(PortName); // 串口地址
            mSerialPortHelper.setBaudRate(BAUDRATE.getBaudrate(BAUDRATE.B9600)); // 波特率 9600
            mSerialPortHelper.setStopBits(STOPB.getStopBit(STOPB.B1)); // 停止位 1
            mSerialPortHelper.setDataBits(DATAB.getDataBit(DATAB.CS8)); // 数据位 8
            mSerialPortHelper.setParity(PARITY.getParity(PARITY.EVEN)); // 校验位 偶校验
            mSerialPortHelper.setFlowCon(FLOWCON.getFlowCon(FLOWCON.NONE)); // 流控 None
            mSerialPortHelper.setFlags(0); // Flag
        }

        // 获得所有串口设备的地址
        getAllDeicesPath();
        // 设置串口打开的监听
        mSerialPortHelper.setIOpenSerialPortListener(new IOpenSerialPortListener() {

            @Override
            public void onOpenSuccess(final File device) {
                L.i(new StringBuffer().append("串口 ").append(device.getPath()).append(" 打开成功"));
            }

            @Override
            public void onOpenFail(final File device, final Status status) {
                switch (status) {
                    case NO_READ_WRITE_PERMISSION:
                        SerialPortTtys2CallBack.onSerialPortOpenListener(false, device.getPath(), "没有读写权限");
                        L.i(new StringBuffer().append("串口 ").append(device.getPath()).append(" 没有读写权限"));
                        break;
                    case OPEN_FAIL:
                    default:
                        SerialPortTtys2CallBack.onSerialPortOpenListener(false, device.getPath(), "串口打开失败");
                        L.i(new StringBuffer().append("串口 ").append(device.getPath()).append(" 串口打开失败"));
                        break;
                }
            }
        });
        // 设置串口数据收发的监听
        mSerialPortHelper.setISerialPortDataListener(new ISerialPortDataListener() {
            /**
             * 串口接收数据回调
             * @param bytes 接收的byte数组
             */
            @Override
            public void onDataReceived(byte[] bytes) {
                L.i(PortName + "回传数据: ", byteArrToHex(bytes));
                receiveParsingData(byteArrToHex(bytes), bytes);
            }

            /**
             * 向串口发送数据
             * @param bytes 发送的数据
             */
            @Override
            public void onDataSend(byte[] bytes) {
                L.i(PortName + "发送数据: ", byteArrToHex(bytes));
            }
        });

        // 打开串口
        boolean isOpen = mSerialPortHelper.open();
        isSerialPortOpen = isOpen;
        return isOpen;
    }

    /**
     * 获得所有串口设备的地址
     *
     * @return String[]
     */
    public static String[] getAllDeicesPath() {
        if (isSerialPortOpen) {
            String[] deicesPaths = mSerialPortHelper.getAllDeicesPath();
            L.i("所有串口设备的地址:", Arrays.toString(deicesPaths));
            return deicesPaths;
        } else {
            return new String[]{};
        }
    }

    // =================================================================== 发送串口数据

    /**
     * 发送串口数据
     *
     * @param data 拼接好的串口数据十进制字符串
     */
    public static void sendTex(String data) {
        if (mSerialPortHelper != null && isSerialPortOpen) {
            data = data.toUpperCase(); // 将字符串字母全部转换为大写
            mSerialPortHelper.sendHex(data); // 发送数据
        }
    }

    /**
     * 发送数据
     *
     * @param bytes 发送的字节
     * @return 发送状态 true:发送成功 false：发送失败
     */
    public static void sendBytes(byte[] bytes) {
        mSerialPortHelper.sendBytes(bytes);
    }

    /**
     * 发送Hex字符串
     *
     * @param hex 16进制文本
     */
    public static void sendHex(String hex) {
        hex = hex.toUpperCase(); // 将字符串字母全部转换为大写
        mSerialPortHelper.sendHex(hex);
    }

    // =================================================================== 发送串口数据

    /**
     * 关闭串口
     *
     * @return 关闭结果 true：关闭成功  false：产生异常等关闭失败
     */
    public static boolean close() {
        if (mSerialPortHelper != null && isSerialPortOpen) {
            try {
                mSerialPortHelper.close();
                isSerialPortOpen = false;
                return true;
            } catch (Exception e) {
                L.e("串口关闭失败", e.toString());
            }
        }
        return false;
    }

    /**
     * 回传数据处理
     *
     * @param resultData  返回的String格式的字符串
     * @param resultBytes 返回的byte数组，两个参数回传内容一致，方便兼容之前的逻辑代码
     */
    public static void receiveParsingData(String resultData, byte[] resultBytes) {
        SerialPortTtys2CallBack.doCallBackMethod(resultData, resultBytes);
    }

}